// 使用validate hook进行数据校验
export const useValidate = () => {
  // 内置的校验消息
  const message = {
    number: "$0只能是数字",
    chinese: "$0只能是中文",
    email: "$0格式不正确",
    idcard: "$0格式不正确",
    phone: "$0格式不正确",
    require: "$0不能为空",
    length: "$0长度只能是$1到$2个字符",
    min: "$0至少$1个字符",
    max: "$0不能超过$1个字符",
    eq: "$0只能是$1",
    neq: "$0不能为$1",
    gt: "$0不能小于$1",
    lt: "$0不能大于$1",
    between: "$0值只能在$1到$2之间",
    in: "$0只能取$n",
    confirm: "$0与:1不一致",
    requireBy: "$0不能为空",
  };
  // 内置的校验规则
  const testObj = {
    number: /^-?\d*\.?\d+$/,
    chinese: /^[\u4e00-\u9fa5]+$/,
    email: /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/,
    idcard:
      /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
    phone: /^[1][3-9][0-9]{9}$/,
    require: function (v) {
      return v !== null && v != undefined && v !== "";
    },
    length: function (v, m, n) {
      return !(("" + v).length < m || ("" + v).length > n);
    },
    min: function (v, l) {
      return ("" + v).length >= l;
    },
    max: function (v, l) {
      return ("" + v).length <= l;
    },
    eq: function (v, m) {
      return v == m;
    },
    neq: function (v, m) {
      return v != m;
    },
    gt: function (v, m) {
      return v > m;
    },
    lt: function (v, m) {
      return v < m;
    },
    between: function (v, m, n) {
      if (isNaN(v)) return false;
      return v > m && v < n;
    },
    in: function () {
      for (let i = 1, len = arguments.length; i < len; i++)
        if (arguments[0] == arguments[i]) return true;
      return false;
    },
    confirm: function (v, m) {
      return v == globalData[m];
    },
    requireBy: function (v, m, v2) {
      if (globalData[m] == v2) {
        return v !== null && v != undefined && v !== "";
      } else {
        return true;
      }
    },
  };
  var globalData = {};
  // 更新校验规则
  function rule(name, rule, msg) {
    testObj[name] = rule ? rule : testObj[name];
    message[name] = msg ? msg : message[name];
    return;
  }
  // 解析校验规则字符串
  function parse(rule) {
    var s = rule.split("!"),
      s2 = s[0].split(":");
    return {
      name: s2[0],
      args: s2.length == 2 ? s2[1].split(",") : [],
      msg:
        s.length == 2 ? s[1] : message[s2[0]] ? message[s2[0]] : "$0格式不对",
    };
  }
  // 格式化校验规则
  function format(rule) {
    var data = {};
    for (let i in rule) {
      let item = rule[i].split("|"),
        t = { name: i, rule: [] };
      while (item.length > 0) {
        var j = item.shift();
        if (j[0] == "@") t.name = j.substr(1);
        else t.rule.push(parse(j));
      }
      data[i] = t;
    }

    return data;
  }
  // 进行校验
  function check(rule, data, all) {
    var result = {};
    if (typeof rule == "string" && typeof data == "string") {
      rule = { field: rule };
      data = { field: data };
    }
    rule = format(rule);
    globalData = data;
    for (let i in rule) {
      let items = rule[i].rule;

      for (let j in items) {
        var fn = testObj[items[j].name];

        if (!fn) continue;
        var test =
          typeof fn == "function"
            ? fn.apply(this, [data[i], ...items[j].args])
            : fn.test(data[i]);
        if (test !== true) {
          var tpl = [rule[i].name, ...items[j].args],
            msg = items[j].msg.replace(/[$:]{1}[\dn]*/g, function (v) {
              if (v[0] == ":") return rule[tpl[v.substr(1)]].name;
              if (v == "$n") return items[j].args.join(",");
              return tpl[v.substr(1)];
            });
          if (all) result[i] = msg;
          else return msg;
        }
      }
    }
    if (JSON.stringify(result) != "{}") return result;
    else return true;
  }
  // 导出check方法
  return {
    check,
  };
};
